<?php

/**
 * This is the model class for table "msgg_channel_log".
 *
 * The followings are the available columns in table 'msgg_log':
 * @property integer $id
 * @property integer $iid
 * @property string $ext_id
 * @property string $ext_status
 * @property string $channel
 * @property string $type
 * @property integer $status
 * @property integer $time
 * @property string $params
 * @property string $result
 * @property string $callback_params
 * @property string $conf
 * @property string $time_create
 * @property string $time_update
 */
class MsggChannelLog extends CActiveRecord
{
    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'msgg_channel_log';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        return array(
            array('status', 'required'),
            array('ext_id, type,ext_status,channel', 'length', 'max' => 128),
            array('params, result, conf,callback_params, time_create, time_update,time', 'safe'),
            array(
                'id,iid, ext_id,ext_status, type, status, params,time, result, callback_params, time_create, time_update,channel,conf',
                'safe',
                'on' => 'search'
            ),
            array(
                'time',
                'default',
                'value' => time(),
                'setOnEmpty' => false,
                'on' => 'insert'
            ),
            array(
                'time_update',
                'default',
                'value' => new CDbExpression('NOW()'),
                'setOnEmpty' => false,
                'on' => 'update'
            ),
            array(
                'time_create, time_update',
                'default',
                'value' => new CDbExpression('NOW()'),
                'setOnEmpty' => false,
                'on' => 'insert'
            ),
        );
    }

    public function relations()
    {
        return array(
            'msgItem' => array(self::HAS_ONE, 'MsggItem', ['id' => 'iid']),
            'msgItemHooks' => array(self::HAS_MANY, 'MsggItemHook', ['lid' => 'id']),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'iid' => 'IID',
            'ext_id' => 'Ext ID',
            'ext_status' => 'Ext Status',
            'channel' => 'Channel',
            'type' => 'Type',
            'time' => 'Time',
            'status' => 'Status',
            'params' => 'Params',
            'result' => 'Result',
            'conf' => 'Conf',
            'time_create' => 'Time Create',
            'time_update' => 'Time Update',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical useCase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        $criteria = new CDbCriteria;
        $criteria->compare('id', $this->id);
        $criteria->compare('iid', $this->iid);
        $criteria->compare('ext_id', $this->ext_id, true);
        $criteria->compare('channel', $this->channel, true);
        $criteria->compare('ext_status', $this->ext_status, true);
        $criteria->compare('type', $this->type, true);
        $criteria->compare('time', $this->time, true);
        $criteria->compare('status', $this->status, true);
        $criteria->compare('params', $this->params, true);
        $criteria->compare('result', $this->result, true);
        $criteria->compare('conf', $this->conf, true);
        $criteria->compare('time_create', $this->time_create, true);
        $criteria->compare('time_update', $this->time_update, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }


    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public static function build($attrs = [])
    {
        $log = new self();
        $ts = time();
        $attributes = array(
            'iid' => 0,
            'ext_id' => (!isset($attrs['ext_id'])) ? null : $attrs['ext_id'],
            'ext_status' => isset($attrs['ext_status']) ? $attrs['ext_status'] : null,
            'channel' => (!isset($attrs['channel'])) ? null : $attrs['channel'],
            'type' => (!isset($attrs['type'])) ? null : $attrs['type'],
            'time' => isset($attrs['time']) ? $attrs['time'] : $ts,
            'status' => (!isset($attrs['status'])) ? null : $attrs['status'],
            'params' => json_encode((!isset($attrs['params']) || !is_array($attrs['params'])) ? [] : $attrs['params']),
            'result' => json_encode((!isset($attrs['result']) || !is_array($attrs['result'])) ? [] : $attrs['result']),
            'conf' => json_encode((!isset($attrs['conf']) || !is_array($attrs['conf'])) ? [] : $attrs['conf']),
        );
        $log->attributes = $attributes;
        return $log;
    }

    public static function updateExtStatus($extId, $extStatus, $hookParams = array())
    {
        $res = false;
        $log = self::model()->findByAttributes(array('ext_id' => $extId));
        if ($log && $item = $log->msgItem) {
            switch ($item->type) {
                case MsggItem::TYPE_SMS:
                    $status = MsggSms::mapStatus($extStatus);
                    break;
                case MsggItem::TYPE_CALL:
                    $status = MsggCall::mapStatus($extStatus);
                    break;
            }
            $log->status = $status;
            $log->ext_status = $extStatus;
            $log->save();
            if ($item->getExtId() == $extId && ($item->isHooking() || $item->isRunning())) {
                $item->status = $status;
                if (($item->isComplete() || $item->isFailure()) && (count($item->getResult()) <= $item->retry)) {
                    $item->status = MsggItem::STATUS_RETRYING;
                }
                //when hook is fail and retry is null
                if ($item->isFailure() && $item->retry == 0 && count($item->getResult()) <= 1) {
                    $item->status = MsggItem::STATUS_RETRYING;
                }
                $res = $item->save();
                if ($res) {
                    $item->onAfterHook(new CEvent($item, []));
                } else {
                    Yii::log('updateExtStatus data:' . json_encode($item->getErrors()), CLogger::LEVEL_ERROR, 'msggChannelLog.updateStatus');
                }
            }
            MsggItemHook::add(($item ? $item->id : null), ($log ? $log->id : null), $hookParams);
        }
        return $res;
    }

    public function getParams()
    {
        $_params = null;
        if (!empty($this->params)) {
            $_params = json_decode($this->params, true);
        }
        return $_params;
    }


}
